#coding=utf8

IGNORE_V = '$'

def idict_idx(d, k):
    v = d[k]
    if v == IGNORE_V:
        raise KeyError('{} is INGORE_V'.format(k))
    return v


def idict_in(d, k):
    try:
        idict_idx(d, k)
        return True
    except KeyError:
        return False


class ChainMap(object):
    def __init__(self, *maps):
        self.maps = maps

    def __repr__(self):
        return ', '.join([str(m) for m in self.maps])

    def __getitem__(self, key):
        for m in self.maps[:-1]:
            try:
                return idict_idx(m, key)
            except KeyError:
                pass

        return idict_idx(self.maps[-1], key)

    def __contains__(self, key):
        for m in self.maps:
            if idict_in(m, key):
                return True

        return False

    def get(self, key, val=None):
        try:
            return self.__getitem__(key)
        except IndexError:
            return val
